#include "Tree.h"


Tree::Tree(Info* pInfo)
{
	m_pInfo=pInfo;
	m_pHeap=new Heap<MIN_TYPE,Node>(m_pInfo->NumOfSymbols());

	CreateLeaves();
	CreateRoot();

	delete m_pHeap;
}


Tree::~Tree()
{
	DestroyLeaves();
	DestroyRoot();
}


Node** Tree::GetLeaves()
{
	return m_aLeaves;
}


Node* Tree::GetRoot()
{
	return m_pRoot;
}


void Tree::CreateLeaves()
{
	int* aSymbolVector=m_pInfo->SymbolVector();
	int* aSymCntVector=m_pInfo->SymCntVector();

	m_aLeaves=new Node*[m_pInfo->SymbolsRange()];
	for (int i=0; i<m_pInfo->NumOfSymbols(); i++)
	{
		m_aLeaves[aSymbolVector[i]]=new Node(aSymbolVector[i],NO_NODE);
		(int&)(*m_aLeaves[aSymbolVector[i]])=aSymCntVector[i];
		m_pHeap->AddItem(m_aLeaves[aSymbolVector[i]]);
	}
}


void Tree::CreateRoot()
{
	Node* pChild0;
	Node* pChild1;

	for (int i=0; i<m_pInfo->NumOfSymbols()-1; i++)
	{
		m_pHeap->GetBest(&pChild0);
		m_pHeap->GetBest(&pChild1);
		m_pHeap->AddItem(new Node(pChild0,pChild1));
	}
	m_pHeap->GetBest(&m_pRoot);
}


void Tree::DestroyLeaves()
{
	delete[] m_aLeaves;
}


void Tree::DestroyRoot()
{
	Node* pParent;
	if (m_pRoot!=NO_NODE)
	{
		pParent=m_pRoot;
		m_pRoot=pParent->Child0();
		DestroyRoot();
		m_pRoot=pParent->Child1();
		DestroyRoot();
		delete pParent;
	}
}
